All files / src/components ThemeProvider.tsx

0% Statements 0/36
0% Branches 0/19
0% Functions 0/6
0% Lines 0/33

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65                                                                                                                                 
'use client';
 
import { useEffect } from 'react';
import { STORAGE_KEYS, THEME } from '@/constants/app';
 
function applyTheme(theme: string) {
  const root = document.documentElement;
  // Remove previous theme classes
  root.classList.remove('dark', 'theme-midnight', 'theme-darkblue');
 
  switch (theme) {
    case THEME.DARK:
      root.classList.add('dark');
      break;
    case THEME.MIDNIGHT:
      root.classList.add('dark');
      root.classList.add('theme-midnight');
      break;
    case THEME.DARK_BLUE:
      root.classList.add('dark');
      root.classList.add('theme-darkblue');
      break;
    case THEME.SYSTEM: {
      const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
      if (prefersDark) root.classList.add('dark');
      break;
    }
    case THEME.LIGHT:
    default:
      // Light: no extra class (variables from :root)
      break;
  }
}
 
export default function ThemeProvider() {
  useEffect(() => {
    const stored = (typeof window !== 'undefined' && localStorage.getItem(STORAGE_KEYS.THEME)) || THEME.SYSTEM;
    applyTheme(stored);
    // Respond to system changes when in SYSTEM mode
    const mq = window.matchMedia('(prefers-color-scheme: dark)');
    const listener = () => {
      const current = localStorage.getItem(STORAGE_KEYS.THEME) || THEME.SYSTEM;
      if (current === THEME.SYSTEM) applyTheme(current);
    };
    mq.addEventListener?.('change', listener);
    return () => mq.removeEventListener?.('change', listener);
  }, []);
  return null;
}
 
// Optional helper for runtime theme switching from anywhere:
// window.setAppTheme('midnight' | 'dark_blue' | 'dark' | 'light' | 'system')
declare global {
  interface Window { setAppTheme?: (theme: string) => void }
}
 
if (typeof window !== 'undefined') {
  window.setAppTheme = (theme: string) => {
    try {
      localStorage.setItem(STORAGE_KEYS.THEME, theme);
      applyTheme(theme);
    } catch (_) { /* ignore */ }
  };
}